package logic

import (
	"errors"
	"project/study-go/ecode"
	"project/study-go/logger"
	"project/study-go/util"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gofrs/uuid"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"

	"project/study-go/db"
	"project/study-go/model"
)

type AccountLogic struct{}

var DefaultAccount = AccountLogic{}

//CreateUser 创建用户
func (u AccountLogic) CreateUser(c *gin.Context) error {
	var (
		username string = c.GetString("username")
		password string = c.GetString("password")
		email    string = c.GetString("email")
		err      error
	)

	//生成uuid
	uid := uuid.Must(uuid.NewV4())

	//生成bcrypt算法加密后的密码
	password = c.GetString("password")
	encryptPasswd, err := util.Encrypt([]byte(password))
	if err != nil {
		return err
	}

	newUser := model.UserRegistry{
		Uid:          uid.String(),
		Username:     username,
		Password:     string(encryptPasswd),
		Email:        email,
		LoginIP:      c.ClientIP(),
		LoginTime:    time.Now(),
		RegisterTime: time.Now(),
	}

	newUserInfo := model.UserInfo{
		Uid: newUser.Uid,
		Username: newUser.Username,
		Email: newUser.Email,
	}

	//入库
	result := db.MasterDB.Create(&newUser)
	if result.Error != nil && result.RowsAffected == 0 {
		return result.Error
	}

	result = db.MasterDB.Create(&newUserInfo)
	if result.Error != nil && result.RowsAffected == 0 {
		return result.Error
	}


	c.Set("uid", uid)
	return nil
}

//UserRegisterExist 用户注册信息检查
func (u AccountLogic) UserRegisterExist(c *gin.Context) error {
	//查询用户名
	userReg := &model.UserRegistry{}
	username := c.GetString("username")
	result := db.MasterDB.Select("username").Where("username=?", username).First(userReg)
	if result.Error == nil && result.RowsAffected == 1 {
		return errors.New("用户名已存在")
	}

	//查询邮箱
	email := c.GetString("email")
	result = db.MasterDB.Select("email").Where("email=?", email).First(userReg)
	if result.Error == nil && result.RowsAffected == 1 {
		return errors.New("邮箱已存在")
	}

	return nil
}

//Login 用户登录逻辑
func (u AccountLogic) Login(c *gin.Context, uLogin model.UserLogin) ecode.ErrorCode {
	//检查用户是否存在
	user, errCode := u.GetUserByUsername(uLogin.Username)
	if errCode.Err != nil {
		return errCode
	}

	//校验密码
	err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(uLogin.Password))
	if err != nil {
		return ecode.ErrorCode{ecode.ErrPassword, 401}
	}

	//更新用户登录信息
	updateUser := &model.UserRegistry{}
	updateUser.LoginIP = c.ClientIP()
	updateUser.LoginTime = time.Now()
	updateUser.Uid = user.Uid

	//用户登录后更新register表登录信息
	errCode = u.UpdateUserRegister(updateUser)
	if errCode.Err != nil {
		return errCode
	}

	c.Set("uid", user.Uid)
	c.Set("username", user.Username)
	c.Set("email", user.Email)
	return ecode.ErrorCode{nil, 200}
}

//UidExist 用户是否注册
func (u AccountLogic) UidExist(uid string) ecode.ErrorCode {
	userReg := &model.UserRegistry{}
	result := db.MasterDB.Select("uid").Where("uid=?", uid).First(userReg)
	if result.Error == gorm.ErrRecordNotFound {
		return ecode.ErrorCode{ecode.ErrNotRegister, 403}
	} else if result.Error != nil {
		return ecode.ErrorCode{ecode.ErrInternalError, 500}
	}
	return ecode.ErrorCode{nil, 200}
}

//UserameExist 用户名是否注册
func (u AccountLogic) UserameExist(username string) ecode.ErrorCode {
	userReg := &model.UserRegistry{}
	result := db.MasterDB.Select("username").Where("username=?", username).First(userReg)
	if result.Error == gorm.ErrRecordNotFound {
		return ecode.ErrorCode{ecode.ErrUsernameNotRegister, 400}
	} else if result.Error != nil {
		return ecode.ErrorCode{ecode.ErrInternalError, 500}
	}
	return ecode.ErrorCode{nil, 200}
}

//EmailExist 邮箱是否注册
func (u AccountLogic) EmailExist(email string) ecode.ErrorCode {
	userReg := &model.UserRegistry{}
	result := db.MasterDB.Select("email").Where("email=?", email).First(userReg)
	if result.Error == gorm.ErrRecordNotFound {
		return ecode.ErrorCode{ecode.ErrEmailNotRegister, 400}
	} else if result.Error != nil {
		return ecode.ErrorCode{ecode.ErrInternalError, 500}
	}
	return ecode.ErrorCode{nil, 200}
}

//GetUserByUsername 通过用户名查询用户
func (u AccountLogic) GetUserByUsername(username string) (*model.UserRegistry, ecode.ErrorCode) {
	userReg := &model.UserRegistry{}
	result := db.MasterDB.Where("username=?", username).First(userReg)
	if result.Error == gorm.ErrRecordNotFound {
		return nil, ecode.ErrorCode{ecode.ErrUsernameNotRegister, 400}
	} else if result.Error != nil {
		return nil, ecode.ErrorCode{ecode.ErrInternalError, 500}
	}
	return userReg, ecode.ErrorCode{nil, 200}
}

//GetUserByUid 通过uid查询用户
func (u AccountLogic) GetUserByUid(uid string) (*model.UserRegistry, ecode.ErrorCode) {
	userReg := &model.UserRegistry{}
	result := db.MasterDB.Where("uid=?", uid).First(userReg)
	if result.Error == gorm.ErrRecordNotFound {
		return nil, ecode.ErrorCode{ecode.ErrUsernameNotRegister, 400}
	} else if result.Error != nil {
		return nil, ecode.ErrorCode{ecode.ErrInternalError, 500}
	}
	return userReg, ecode.ErrorCode{nil, 200}
}

//UpdateUserRegister 更新单个用户信息
func (u AccountLogic) UpdateUserRegister(user *model.UserRegistry) ecode.ErrorCode {
	result := db.MasterDB.Where("uid = ?", user.Uid).Updates(user)
	if result.Error != nil {
		return ecode.ErrorCode{ecode.ErrInternalError, 500}
	}
	return ecode.ErrorCode{nil, 200}
}

//ChgPasswd 根据uid更改用户密码
func (u AccountLogic) ChgPasswd(uid, oldPassword, newPassword string) ecode.ErrorCode {

	//检查用户是否存在
	user, errCode := u.GetUserByUid(uid)
	if errCode.Err != nil {
		return errCode
	}

	//校验密码
	err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(oldPassword))
	if err != nil {
		return ecode.ErrorCode{ecode.ErrPassword, 400}
	}

	//对新密码加密
	encryptPasswd, err := util.Encrypt([]byte(newPassword))
	if err != nil {
		logger.AccessLogger.Error("encrypt password error:")
		return ecode.ErrorCode{ecode.ErrInternalError, 500}
	}
	user.Password = string(encryptPasswd)

	//用户更新密码后 更新register表密码信息
	errCode = u.UpdateUserRegister(user)
	if errCode.Err != nil {
		return errCode
	}
	return ecode.ErrorCode{nil, 200}
}
